package ru.reaperoq.taskmanager.controllers

import jakarta.servlet.http.HttpServletRequest
import org.springframework.http.ResponseEntity
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.web.bind.annotation.*
import ru.reaperoq.taskmanager.dto.Response
import ru.reaperoq.taskmanager.dto.SignUpRequest
import ru.reaperoq.taskmanager.dto.SignUpResponse
import ru.reaperoq.taskmanager.exceptions.TaskManagerException
import ru.reaperoq.taskmanager.getUser
import ru.reaperoq.taskmanager.getUserId
import ru.reaperoq.taskmanager.models.User
import ru.reaperoq.taskmanager.repositories.UserRepository
import ru.reaperoq.taskmanager.services.JwtService
import ru.reaperoq.taskmanager.services.UserService

@RestController
@RequestMapping("/api/user")
class UserController(
    private val userService: UserService,
    private val userRepository: UserRepository,
    private val encoder: PasswordEncoder,
    private val jwtService: JwtService,
) {
    @PostMapping("/register")
    fun registerUser(@RequestBody signUpRequest: SignUpRequest): Response<SignUpResponse> {
        userService.createUser(signUpRequest.copy(password = encoder.encode(signUpRequest.password)).toModel()).let {
            if (it == null) {
                return Response.error(code = 400, message = "Пользователь уже существует")
            } else {
                return Response.success(it.toResponse())
            }
        }
    }

    @PostMapping("/login")
    fun loginUser(@RequestBody signUpRequest: SignUpRequest): Response<SignUpResponse> {
        userService.loginUser(signUpRequest.copy(password = signUpRequest.password).toModel()).let {
            if (it == null) {
                throw TaskManagerException.Unauthorized(message = "Пользователь не найден")
            } else {
                return Response.success(it.toResponse())
            }
        }
    }

    @DeleteMapping("/deleteUser")
    fun deleteUser(req: HttpServletRequest): Response<Long> {
        val user = req.getUser(userRepository, jwtService)
        userRepository.delete(user)
        return Response.success(user.id!!)
    }

    private fun SignUpRequest.toModel() =
        User(
            username = this.username,
            password = this.password,
        )

    private fun User.toResponse() =
        SignUpResponse(
            token = jwtService.generateToken(this),
        )
}